home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / cxxp4w.zip / CHAP04 / WINDOW.CPP
C/C++ Source or Header  |  1993-03-11  |  11KB  |  407 lines

  1. #include "window.hpp"
  2. #include "control.hpp"
  3.  
  4. ATOM aProp, aPropHigh;
  5.  
  6. #if defined( PTR16) || defined (WIN32)
  7.   #define PUTPWIN(hWnd,this) \
  8.     SetProp(hWnd,(LPSTR)MAKELONG(aProp,0),(HANDLE)this)
  9.   #define GETPWIN(hWnd) \
  10.     (Window *)GetProp(hWnd,(LPSTR)MAKELONG(aProp,0))
  11.   #define DELPWIN(hWnd) \
  12.     (Window *)RemoveProp(hWnd,(LPSTR)MAKELONG(aProp,0))
  13. #else
  14.   #define PUTPWIN(hWnd,this)\
  15.     SetProp(hWnd,(LPSTR)MAKELONG(aProp,0),(HANDLE)this);\
  16.     SetProp(hWnd,(LPSTR)MAKELONG(aPropHigh,0),\
  17.     (HANDLE)((DWORD)this >>16))
  18.   #define GETPWIN(hWnd) (Window *)\
  19.     ((DWORD)GetProp(hWnd,(LPSTR)MAKELONG(aProp,0))|\
  20.     ((DWORD)GetProp(hWnd,(LPSTR)MAKELONG(aPropHigh,0)) <<16))
  21.   #define DELPWIN(hWnd) (Window *)\
  22.     ((DWORD)RemoveProp(hWnd,(LPSTR)MAKELONG(aProp,0))|\
  23.     ((DWORD)RemoveProp(hWnd,(LPSTR)MAKELONG(aPropHigh,0)) <<16))
  24. #endif // PTR16
  25.  
  26. // Routines to associate instance pointers with windows
  27. void PutWin(HWND hWnd, Window * pWin) { PUTPWIN(hWnd,pWin);};
  28. Window * GetWin(HWND hWnd) {return GETPWIN(hWnd);};
  29. Window*  DelWin(HWND hWnd) {return DELPWIN(hWnd);};
  30.  
  31. //#ifdef WIN32
  32. //  WNDPROC Window::Handler;
  33. //#else
  34.   FARPROC Window::Handler;        // proc instance for CPPWinProc
  35. //#endif
  36. HANDLE Window::hAccel;          // Current accelerator table
  37.  
  38. //  Set window message proc to CPPWinProc
  39. void Window::SetHandler()
  40. {
  41. //#ifdef WIN32
  42. //  DefaultHandler = (WNDPROC) GetWindowLong(hWnd,GWL_WNDPROC);
  43. //#else
  44.   DefaultHandler = (FARPROC) GetWindowLong(hWnd,GWL_WNDPROC);
  45. //#endif
  46.   SetWindowLong(hWnd,GWL_WNDPROC,(LONG) Handler);
  47. PUTPWIN(hWnd,(HANDLE) this);
  48. }
  49.  
  50. // Create a window
  51. void Window::Create(LPSTR caption, LONG style, int x, int y,
  52.         int width, int height, HWND hPwnd, HMENU hMenu)
  53. {
  54.  
  55.   WNDCLASS wc;
  56.   wc.style         = 0;
  57.   wc.lpfnWndProc   = (WNDPROC) DefWindowProc;
  58.   wc.cbClsExtra    = 0;
  59.   wc.cbWndExtra    = 0;
  60.   wc.hInstance     = hInst;
  61.   wc.hIcon         = LoadIcon(NULL,IDI_APPLICATION);
  62.   wc.hCursor       = LoadCursor(NULL,IDC_ARROW);
  63.   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  64.   wc.lpszMenuName  = 0;
  65.  
  66.   hWnd = CreateWindow(Register(wc),
  67.                         caption,style,x,y,width,height,
  68.                         hPwnd,hMenu,hInst,NULL);
  69.  
  70.   if (!hWnd) Error(IDS_APPLERROR, (LPSTR)"Window Creation");
  71.   SetHandler();
  72. }
  73.  
  74. Window::Window() {
  75.   hWnd=0;
  76.   HorzScrollBar=VertScrollBar=NULL;
  77.   if (!Handler) {
  78.   #ifdef WIN32
  79.     Handler = (FARPROC)CPPWinProc;
  80.   #else
  81.     Handler = MakeProcInstance((FARPROC)CPPWinProc, hInst);
  82.   #endif
  83.     aProp=AddAtom("pWindow");
  84.     aPropHigh=AddAtom("pWindowHigh");
  85.   }
  86. }
  87.  
  88. LPSTR Window::Register(WNDCLASS& wc) {
  89.     Error(IDS_APPLERROR,(LPSTR)"No Register method");
  90. return NULL;
  91. }
  92.  
  93. Window::~Window()
  94. {
  95.   if (HorzScrollBar) delete HorzScrollBar;
  96.   if (VertScrollBar) delete VertScrollBar;
  97.  
  98.   if (hWnd) {
  99.     Show(SW_HIDE);
  100.     //Destroy instances associated with child windows
  101.     HWND hCwnd= GetWindow (hWnd, GW_CHILD);
  102.     while ( hCwnd ){
  103.        Window * pWin=(Window*) GETPWIN(hCwnd);
  104.        do {
  105.             hCwnd=GetWindow(hCwnd,GW_HWNDNEXT);
  106.        } while (hCwnd  && GetParent(hCwnd)!=hWnd);
  107.        if (pWin) delete pWin;
  108.     }
  109.  
  110.     if (DELPWIN(hWnd) && DefaultHandler)
  111.       SetWindowLong(hWnd,GWL_WNDPROC,(LONG) DefaultHandler);
  112.     //if this is the top level window quit the application
  113.     if (!GetParent(hWnd)) PostQuitMessage(0);
  114.     DestroyWindow(hWnd);
  115.     hWnd=0;
  116.   }
  117. }
  118.  
  119. // The application message loop
  120. int Window::MessageLoop()
  121. {
  122.     MSG msg;
  123.     while (GetMessage(&msg, NULL, 0, 0)) {
  124.       if(   msg.message >=WM_KEYFIRST 
  125.          && msg.message <=WM_KEYLAST) {
  126.          Window * pWin=GETPWIN(GetParent(msg.hwnd));
  127.          if (pWin && pWin->DialogMessage(msg)) continue;
  128.       }
  129.       if (!hAccel ||
  130.         !TranslateAccelerator (hWnd, hAccel, &msg)){
  131.         TranslateMessage (&msg);
  132.         DispatchMessage (&msg);
  133.       }
  134.     }
  135.     return msg.wParam;
  136. }
  137.  
  138.  
  139. // The window message function, translates messages
  140. // to calls to virtual functions
  141. LONG Window::MessageProc( HWND hWnd, UINT msg, Event& evt)
  142. {
  143.   POINT Pt;
  144.  
  145.   switch (msg){
  146.  
  147.     case WM_QUERYENDSESSION:
  148.       // OK to end Windows session?
  149.       return QueryClose();
  150.  
  151.     case WM_CLOSE:
  152.       // if OK delete this instance
  153.       if (QueryClose ()) delete this;
  154.       return TRUE;
  155.       
  156.     case WM_DESTROY:
  157.       if (DELPWIN(hWnd) && DefaultHandler)
  158.         SetWindowLong(hWnd,GWL_WNDPROC,(LONG) DefaultHandler);
  159.       Window::hWnd=0;
  160.       delete this;
  161.       break;
  162.           
  163.     case WM_INITMENU:
  164.       return InitMenu((HMENU)evt.wParam);
  165.  
  166.     case WM_SIZE:
  167.       return Size(LOWORD(evt.lParam),
  168.                   HIWORD(evt.lParam),evt.wParam);
  169.  
  170.     case WM_PAINT:
  171.       return Paint();
  172.  
  173.     case WM_SETFOCUS:
  174.       return SetFocus((HWND)evt.wParam);
  175.  
  176.     case WM_KILLFOCUS:
  177.       return KillFocus((HWND)evt.wParam);
  178.  
  179.     case WM_CHAR:
  180.       return Char(evt.wParam, LOWORD(evt.lParam));
  181.  
  182.     case WM_KEYDOWN:
  183.       if (KeyDown(evt.wParam, 
  184.          *(KEYCODES*)&evt.lParam)) return TRUE;
  185.       if (VertScrollBar && 
  186.         VertScrollBar->KeyDown(evt.wParam, 
  187.         *(KEYCODES*)&evt.lParam)) return TRUE;
  188.       if (HorzScrollBar && 
  189.         HorzScrollBar->KeyDown(evt.wParam, 
  190.         *(KEYCODES*)&evt.lParam)) return TRUE;
  191.       return FALSE;
  192.  
  193.     case WM_LBUTTONDOWN:
  194.       Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
  195.       return LButtonDown(Pt, evt.wParam);
  196.  
  197.     case WM_LBUTTONUP:
  198.       Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
  199.       return LButtonUp(Pt, evt.wParam);
  200.  
  201.     case WM_LBUTTONDBLCLK:
  202.       Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
  203.       return LButtonDblClk(Pt, evt.wParam);
  204.       
  205.     case WM_RBUTTONDOWN:
  206.       Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
  207.       return RButtonDown(Pt, evt.wParam);
  208.  
  209.     case WM_RBUTTONUP:
  210.       Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
  211.       return RButtonUp(Pt, evt.wParam);
  212.       
  213.     case WM_MOUSEMOVE:
  214.       Pt.x=LOWORD(evt.lParam); Pt.y=HIWORD(evt.lParam);
  215.       return MouseMove(Pt, evt.wParam);
  216.       
  217.     case WM_MOUSEACTIVATE:
  218.       MouseActivate((HWND)evt.wParam, LOWORD(evt.lParam));
  219.       if(DefaultHandler)
  220.     return CallWindowProc (DefaultHandler,
  221.            hWnd, msg, evt.wParam, evt.lParam);
  222.       else return FALSE;
  223.  
  224.  
  225.     case WM_COMMAND:
  226.     {
  227.       WORD wNotifyCode;         // notification code
  228.       WORD wID;                 // item, control, or accelerator ID
  229.       HWND hWndCtl;             // handle of control
  230.  
  231. #ifdef WIN32
  232.       wNotifyCode = HIWORD(evt.wParam); 
  233.       wID = LOWORD(evt.wParam); 
  234.       hWndCtl = (HWND) evt.lParam; 
  235. #else
  236.       wID = (int) evt.wParam; 
  237.       hWndCtl = (HWND) LOWORD(evt.lParam);
  238.       wNotifyCode = HIWORD(evt.lParam); 
  239. #endif
  240.       if (hWndCtl) {
  241.         // if message is from a control, call the control method
  242.     Control * pControl =
  243.       (Control*) (void*)GETPWIN(hWndCtl);
  244.     if (pControl)
  245.       return pControl->CodeHandler(wNotifyCode);
  246.       }
  247.       return Command(wID,wNotifyCode, hWndCtl);
  248.     }
  249.  
  250.     case WM_DRAWITEM:
  251.     {
  252.       // Call DrawItem method in control
  253.       Control * pControl=
  254.     (Control*) (void*)GETPWIN((HWND)
  255.       (((DRAWITEMSTRUCT FAR *) evt.lParam)->hwndItem));
  256.       if (pControl)
  257.         pControl->DrawItem((DRAWITEMSTRUCT FAR * )evt.lParam);
  258.       break;
  259.     }
  260.  
  261. #ifdef WIN32       
  262.     case  WM_CTLCOLORMSGBOX:
  263.     case  WM_CTLCOLOREDIT:
  264.     case  WM_CTLCOLORLISTBOX:
  265.     case  WM_CTLCOLORBTN:
  266.     case  WM_CTLCOLORDLG:
  267.     case  WM_CTLCOLORSCROLLBAR:
  268.     case  WM_CTLCOLORSTATIC:
  269. #else
  270.     case  WM_CTLCOLOR:
  271. #endif
  272.     {
  273.       // Call CtlColor method in control
  274.       Control * pControl=
  275.          (Control*) (void*)GETPWIN((HWND)evt.lParam);
  276.       HBRUSH Brush=NULL;
  277.       if (pControl) Brush=pControl->CtlColor((HDC)evt.wParam);
  278.       if (Brush) return (LONG)Brush;
  279.       if(DefaultHandler)
  280.     return CallWindowProc (DefaultHandler,
  281.            hWnd, msg, evt.wParam, evt.lParam);
  282.       else return FALSE;
  283.     }
  284.        
  285.     case WM_MEASUREITEM:
  286.     {
  287.       // Call MeasureItem method in control
  288.       MEASUREITEMSTRUCT FAR * pMs=
  289.       (MEASUREITEMSTRUCT FAR *)evt.lParam;
  290.       Control * pControl=
  291.     (Control*) (void*)GETPWIN(GetDlgItem(hWnd,pMs->CtlID));
  292.       if (pControl) pControl->MeasureItem(pMs);
  293.       else {
  294.     pMs->itemHeight=ItemMeasurement::itemHeight;
  295.     pMs->itemWidth=ItemMeasurement::itemWidth;
  296.       }
  297.       break;
  298.     }
  299.  
  300.     case WM_HSCROLL:
  301.     {
  302.       HWND hCtl;
  303.       WORD nPos;
  304. #ifdef WIN32
  305.       hCtl=(HWND)evt.lParam;
  306.       nPos=HIWORD(evt.wParam);
  307. #else
  308.       hCtl=(HWND)HIWORD(evt.lParam);
  309.       nPos=LOWORD(evt.lParam);
  310. #endif
  311.       if (hCtl){
  312.     Control * pScroll=
  313.       (Control *)(void*)GETPWIN(hCtl);
  314.     if (pScroll)
  315.       pScroll->CodeHandler((WORD)evt.wParam,nPos);
  316.       }
  317.       else  if (HorzScrollBar){ 
  318.       ((Control *)(void*)HorzScrollBar)
  319.         ->CodeHandler((WORD)evt.wParam,nPos);
  320.       }
  321.       break;
  322.     }
  323.  
  324.     case WM_VSCROLL:
  325.     {
  326.       HWND hCtl;
  327.       WORD nPos;
  328. #ifdef WIN32
  329.       hCtl=(HWND)evt.lParam;
  330.       nPos=HIWORD(evt.wParam);
  331. #else
  332.       hCtl=(HWND)HIWORD(evt.lParam);
  333.       nPos=LOWORD(evt.lParam);
  334. #endif
  335.       if (hCtl){
  336.     Control * pScroll=
  337.       (Control *)(void*)GETPWIN(hCtl);
  338.     if (pScroll)
  339.       pScroll->CodeHandler((WORD)evt.wParam,nPos);
  340.       }
  341.       else  if (VertScrollBar){ 
  342.       ((Control *)(void*)VertScrollBar)
  343.         ->CodeHandler((WORD)evt.wParam,nPos);
  344.       }
  345.       break;
  346.     }
  347.  
  348.  
  349.     default:
  350.       if (DefaultHandler)
  351.     return CallWindowProc (DefaultHandler,
  352.            hWnd, msg, evt.wParam, evt.lParam);
  353.   } // switch
  354.   return FALSE;
  355. } // MessageProc
  356.  
  357. BOOL Window::Size(UINT Width, UINT Height, UINT Type) {
  358.   if (!DefaultHandler) return FALSE;
  359.   return CallWindowProc (DefaultHandler,
  360.          hWnd, WM_SIZE, Type, MAKELONG(Width, Height));
  361. }
  362.  
  363. BOOL Window::Paint() {
  364.   if (!DefaultHandler) return FALSE;
  365.   return CallWindowProc (DefaultHandler, hWnd, WM_PAINT, 0,0);
  366. }
  367.  
  368. BOOL Window::Command( UINT Id, UINT Code, HWND hControl) {
  369.   if (!DefaultHandler) return FALSE;
  370. #ifdef WIN32
  371.   return CallWindowProc (DefaultHandler,
  372.     hWnd, WM_COMMAND, MAKELONG(Id, Code), (DWORD)hControl);
  373. #else
  374.   return CallWindowProc (DefaultHandler,
  375.     hWnd, WM_COMMAND, Id, MAKELONG(hControl, Code));
  376. #endif
  377. }
  378.  
  379. LONG CALLBACK CPPWinProc(HWND hWnd, UINT Message,
  380.                UINT wParam,LONG lParam)
  381. {
  382.   Window* pWin = GETPWIN(hWnd);
  383.   Event evt(wParam,lParam);
  384.   if (pWin) {
  385.     // There is a C++ instance for the window
  386.     return pWin->MessageProc(hWnd,Message,evt);
  387.   }
  388.   else if (Message== WM_MEASUREITEM) {
  389.     // return the current owner-draw item size
  390.     MEASUREITEMSTRUCT FAR * pMs=
  391.       (MEASUREITEMSTRUCT  FAR *)lParam;
  392.     pMs->itemHeight=ItemMeasurement::itemHeight;
  393.     pMs->itemWidth=ItemMeasurement::itemWidth;
  394.     return TRUE;
  395.   }
  396.   else return FALSE;
  397. } // CPPWinProc
  398.  
  399. void Window::Move(RECT * rc, BOOL repaint) {
  400.   MoveWindow (hWnd,
  401.           rc->left,
  402.           rc->top,
  403.           rc->right-rc->left,
  404.           rc->bottom-rc->top,
  405.           repaint);
  406. }
  407.